package com.salton123.processor.action

import com.salton123.processor.bean.ClzBean
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.TypeSpec
import javax.annotation.processing.ProcessingEnvironment
import javax.annotation.processing.RoundEnvironment
import javax.lang.model.element.ExecutableElement
import javax.lang.model.element.Modifier
import javax.lang.model.element.TypeElement
import javax.tools.Diagnostic

/**
 * @Time:2021/2/4 10:51
 * @Author:wujinsheng
 * @Description:
 */
class RheaRoomProcessDispatch : IProcessDispatch {
    private lateinit var mProcessingEnv: ProcessingEnvironment
    private val mFunMap: HashMap<TypeElement, HashSet<TypeElement>> = HashMap()
    override fun process(roundEnv: RoundEnvironment?, processingEnv: ProcessingEnvironment) {
        this.mProcessingEnv = processingEnv
        note("roundEnv:$roundEnv,processingEnv:$processingEnv")

//        ElementFilter.typesIn(roundEnv?.getElementsAnnotatedWith(RheaRoom::class.java))
//            .forEach {
//                note("newsalton:$it")
//                if (mFunMap[it.enclosingElement] != null) {
//                    mFunMap[it.enclosingElement]?.add(it)
//                } else {
//                    mFunMap[it.enclosingElement as Symbol] =
//                        HashSet<TypeElement>().apply { add(it) }
//                }
//            }
//        note("mFunMap:$mFunMap")
//        generateRheaRoomClass()
    }

    private fun generateRheaRoomClass() {
        mFunMap.forEach { (t, u) ->
            val clzBean = ClzBean(mProcessingEnv, t, u)
            val file = FileSpec.builder(clzBean.packageName, clzBean.implClzName)
                .addType(generateClazz(clzBean).build())
                .build().run {
                    note("newsalton:$this")
                    writeTo(mProcessingEnv.filer)
                }
        }
    }

    private fun generateClazz(clzBean: ClzBean): TypeSpec.Builder {
        val clz = TypeSpec.classBuilder(clzBean.implClzName)
            .addSuperinterface(ClassName.bestGuess("androidx.room.RoomDatabase"))
            .addAnnotation(ClassName.bestGuess("androidx.room.Database"))
        return clz
    }

//    val clzName = "RheaRoomDatabase"
//    private fun generateClazz(): TypeSpec.Builder {
//        val clz = TypeSpec.classBuilder(clzName)
////            .addSuperinterface(ClassName.bestGuess("androidx.room.RoomDatabase"))
////            .addAnnotation(ClassName.bestGuess("androidx.room.Database"))
//        return clz
//    }

    private fun note(msg: String) {
        mProcessingEnv.messager.printMessage(Diagnostic.Kind.NOTE, msg)
    }

    private fun error(msg: String) {
        mProcessingEnv.messager.printMessage(Diagnostic.Kind.ERROR, msg)
    }

    private fun isPublic(element: ExecutableElement): Boolean {
        return element.modifiers.contains(Modifier.PUBLIC)
    }
}

